#include "widget.h"
#include "ui_widget.h"

#include <QButtonGroup>
#include <QAbstractButton>
#include <QDebug>
#include <QToolButton>

/******************************************************************************
 *
 * @file       widget.cpp
 * @brief      默认互斥模式​​：!!!QButtonGroup默认启用互斥（setExclusive(true)），确保组内仅一个按钮可选中（如单选按钮组）(运动控制!)。
               ​​动态管理​​：支持运行时添加/移除按钮（addButton()/removeButton()），适合动态界面需求。
               ​​多线程安全:若按钮状态被多线程访问，需用互斥锁（如QMutex）保护共享数据，防止竞态条件(界面UI都因该在主线程中执行!!!)
 *
 * @author     xiYan
 * @date       2025/06/25
 * @history
 *****************************************************************************/

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->label->setText("");
    initWidget();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initWidget()
{
    useQButtonGroupBase();
    useQButtonGroupEvent();
}

void Widget::useQButtonGroupBase()
{
    QButtonGroup* buttonGroup = new QButtonGroup(this);
    buttonGroup->addButton(ui->pushButton1,buttonGroup->buttons().size());
    buttonGroup->addButton(ui->pushButton2,buttonGroup->buttons().size());

    // +Qt5.7 没有试过
    /*
    connect(buttonGroup,&QButtonGroup::buttonClicked,this,[](QAbstractButton* button){
        qDebug()<<"clicked : "<< button->text();
    });
    */
    // QButtonGroup 有多个 buttonClicked 信号如：void buttonClicked(QAbstractButton *);  // 版本1：返回按钮对象
    //                                         void buttonClicked(int);                // 版本2：返回按钮ID
    // 显式指定
    connect(buttonGroup,
            QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked),
            this,
            [buttonGroup,this](QAbstractButton* button){
                qDebug() << "Clicked:" << button->text() << ";index : " << buttonGroup->id(button);
                ui->label->setText(button->text());
            });

}

// 方式1

void Widget::useQButtonGroupEvent()
{
    // 如需更精细的事件控制（如长按、悬停），可重写按钮的mousePressEvent或使用事件过滤器（installEventFilter）
    m_buttonGroup = new QButtonGroup(this);
    m_buttonGroup->addButton(ui->pushButton3,m_buttonGroup->buttons().size());
    m_buttonGroup->addButton(ui->pushButton4,m_buttonGroup->buttons().size());

    for(int i = 0;i < m_buttonGroup->buttons().size();i++){
        m_buttonGroup->buttons().at(i)->installEventFilter(this); // 绑定过滤器（鼠标、键盘过滤事件）
    }
}

// 这个过滤方法调用太频繁的话,有性能的消耗.(鼠标打开这个界面也会触发这个函数,调试的时候注意哈!)
bool Widget::eventFilter(QObject *_watched, QEvent *_event)
{
    auto btn = qobject_cast<QAbstractButton*>(_watched);
    // if (m_buttonGroup->buttons().contains(dynamic_cast<QToolButton*>(_watched)))
    if (m_buttonGroup->buttons().contains(btn))
    {
        if (_event->type() == QEvent::MouseButtonPress)
        {
            if(btn == ui->pushButton3)
            {
                qDebug() << btn->text();
                ui->label->setText(btn->text());
            }
            else if(btn == ui->pushButton4){
                qDebug() << btn->text();
                ui->label->setText(btn->text());
            }
        }
    }
    return false; // // 不拦截事件，继续传递 而不是return true;
}

// 方式2
/*
void Widget::useQButtonGroupEvent()
{
    m_buttonGroup = new QButtonGroup(this);

    m_buttonGroup->addButton(ui->pushButton3, m_buttonGroup->buttons().size());
    m_buttonGroup->addButton(ui->pushButton4, m_buttonGroup->buttons().size());

    for(auto* btn : m_buttonGroup->buttons()) {
        btn->installEventFilter(this);
    }
}

bool Widget::eventFilter(QObject *_watched, QEvent *_event)
{
    // 统一使用qobject_cast（更高效）
    auto* btn = qobject_cast<QAbstractButton*>(_watched);

    // 直接检查按钮是否在组中
    if(btn && m_buttonGroup->buttons().contains(btn))
    {
        if(_event->type() == QEvent::MouseButtonPress)
        {
            // 更可靠的按钮判断方式
            if(btn == ui->pushButton3)
                qDebug() << "Button 3 pressed:" << btn->text();
            else if(btn == ui->pushButton4)
                qDebug() << "Button 4 pressed:" << btn->text();

            return false; // 允许继续处理事件
        }
    }
    return QObject::eventFilter(_watched, _event);  // 给父类处理
}
*/

